home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / oort / explosion.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.1 KB  |  400 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*------------------------------------------------------------------------------
  18.  *
  19.  * OORT - explosion.c - Routines for creating and displaying explosion.
  20.  *
  21.  * $Id: explosion.c,v 1.4 1994/01/28 00:17:49 mtj Exp $
  22.  * 
  23.  * Chris Fouts - May, 1993.
  24.  * 
  25.  *----------------------------------------------------------------------------*/
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <unistd.h>
  30. #include <fcntl.h>
  31. #include <malloc.h>
  32. #include <gl.h>
  33. #include <Performer/pf.h>
  34.  
  35. #include "oort.h"
  36. #include "explosion.h"
  37.  
  38. #define    EXPLOSION_SWITCH(g)    (pfSwitch *)pfGetChild( (g), 0 )
  39.  
  40.  
  41.  
  42. /* BEGIN PROTOTYPES -S explosion.c */
  43. static void         createExplosions( int rings, int spokes, int frames ) ;
  44. static pfGeode *    makeExplosionFrame( int rings, int spokes, float r,
  45.                         float frame ) ;
  46. /* END PROTOTYPES -S explosion.c */
  47.  
  48. static pfGroup        *baseExplosionGroup ;
  49. static pfSwitch        *explosionSwitch ;
  50. static pfDCS        *explosionDCS ;
  51. static pfGeoState    *expGeoState ;
  52. static pfDCS        *explosionGroup[MAXPLAYERS] ;
  53.  
  54. extern float        gameTime ;
  55. extern float        deadTime[] ;
  56. extern float        frameRate ;
  57. extern int        debugOn ;
  58. extern pfGroup        *trikeSwitch[] ;
  59. extern pfGroup        *pShield[] ;
  60. extern pfGroup        *vehicle[] ;
  61. extern pfMatrix        playerMatrix[] ;
  62. extern pfMatrix        selfMatrix ;
  63. extern pfVec3        ahead ;
  64. extern pfVec3        right ;
  65. extern pfVec3        up ;
  66. extern Player        player[] ;
  67. extern int        numberPlayers ;
  68.  
  69. static struct {
  70.         pfDCS    *location ;
  71.         pfGroup    *frame ;
  72.         } expNodes[MAXPLAYERS] ;
  73.  
  74. #define    EXPL_FRAMES    15
  75.  
  76.  
  77.  
  78.  
  79. /*------------------------------------------------------------------------------
  80.  * Create explosion billboards.
  81.  *----------------------------------------------------------------------------*/
  82. static void
  83. createExplosions(
  84.     int    rings,
  85.     int    spokes,
  86.     int    frames
  87.     )
  88. {
  89.     int    frame ;
  90.     float    minR = (float)( 1.0f * CAR_LENGTH ) ;
  91.     float    maxR = (float)( 2.0f * CAR_LENGTH ) ;
  92.     float    r ;
  93.     float    alpha ;
  94.     pfGeode    *eg ;
  95.  
  96.     /* 
  97.      * create a new geostate from shared memory,
  98.      * disable texturing and enable transparency
  99.      */
  100.     expGeoState = pfNewGState( pfGetSharedArena() ) ;
  101.     pfGStateMode( expGeoState, PFSTATE_ENTEXTURE, 0 ) ;
  102.     pfGStateMode( expGeoState, PFSTATE_TRANSPARENCY, PFTR_ON ) ;
  103.     pfGStateMode( expGeoState, PFSTATE_ENLIGHTING, PF_OFF ) ;
  104.     pfGStateMode( expGeoState, PFSTATE_CULLFACE, PFCF_BACK ) ;
  105.  
  106.     for( frame = 0 ; frame < frames ; frame++ )
  107.     {
  108.         r = minR + ( maxR - minR ) *
  109.             pfSqrt( (float)frame / ( frames - 1.0f ) ) ;
  110.         eg = makeExplosionFrame( rings, spokes, r,
  111.                     (float)frame / ( frames - 1.0f ) ) ;
  112.         pfAddChild( explosionSwitch, eg ) ;
  113.     }
  114. }
  115.  
  116.  
  117.  
  118. /*------------------------------------------------------------------------------
  119.  * Make an explosion frame.
  120.  *----------------------------------------------------------------------------*/
  121. static pfGeode *
  122. makeExplosionFrame(
  123.     int    rings,
  124.     int    spokes,
  125.     float    r,
  126.     float    frame
  127.     )
  128. {
  129.     int        i ;
  130.     int        j ;
  131.     int        ring ;
  132.     int        spoke ;
  133.     long        nPts ;
  134.     long        nIndices ;
  135.     unsigned short    *indices ;
  136.     long        *length ;
  137.     float        theta ;
  138.     float        radius ;
  139.     float        st ;
  140.     float        ct ;
  141.     float        y ;
  142.     float        alpha = 1.0f - frame * 0.8f ;
  143.     pfGeode        *geode ;
  144.     pfGeoSet    *gset ;
  145.     pfVec3        *coords ;
  146.     pfVec4        *colors ;
  147.  
  148.     geode = pfNewGeode() ;
  149.  
  150.     gset = pfNewGSet( pfGetSharedArena() ) ;
  151.  
  152.     length = (long *)myMalloc( rings * sizeof( long ) ) ;
  153.  
  154.     nPts = rings * spokes ;
  155.     coords = (pfVec3 *)myMalloc( nPts * sizeof( pfVec3 ) ) ;
  156.     colors = (pfVec4 *)myMalloc( nPts * sizeof( pfVec4 ) ) ;
  157.  
  158.     nIndices = spokes ;
  159.     length[0] = spokes ;
  160.     for( i = 1 ; i < rings ; i++ )
  161.     {
  162.         length[i] = 2 * ( spokes + 1 ) ;
  163.         nIndices += length[i] ;
  164.     }
  165.     indices = (unsigned short *)myMalloc(
  166.             nIndices * sizeof( unsigned short ) ) ;
  167.  
  168.     /*
  169.      * Assign coordinate points and colors.
  170.      */
  171.     i = 0 ;
  172.     j = 0 ;
  173.     for( ring = 0 ; ring < rings ; ring++ )
  174.     {
  175.         radius = r * (float)( ring + 1 ) / (float)rings ;
  176.         y = pfSqrt( r*r - radius*radius ) ;
  177.         for( spoke = 0 ; spoke < spokes ; spoke++ )
  178.         {
  179.             theta = 360.0f * (float)spoke / (float)spokes ;
  180.             pfSinCos( theta, &st, &ct ) ;
  181.             PFSET_VEC3( coords[i],
  182.                 radius * st,
  183.                 y,
  184.                 CAR_HEIGHT / 2.0f + radius * ct ) ;
  185.             PFSET_VEC4( colors[i],
  186.                 1.00f * ( 1.0f - radius/r ),
  187.                 0.88f * ( 1.0f - radius/r ) *
  188.                     ( 1.0f - 0.5f * frame ),
  189.                 0.0f,
  190.                 alpha ) ;
  191.             i++ ;
  192.         }
  193.         if( ring == 0 )
  194.         {
  195.             for( spoke = 0 ; spoke < spokes ; spoke++ )
  196.             {
  197.                 indices[j] = ( ( spoke + 1 ) % 2 ) * spoke / 2 +
  198.                     ( spoke % 2 ) *
  199.                     ( spokes - ( ( spoke + 1 ) / 2 ) ) ;
  200.                 j++ ;
  201.             }
  202.         }
  203.         else
  204.         {
  205.             for( spoke = 0 ; spoke <= spokes ; spoke++ )
  206.             {
  207.                 indices[j++] = ( ring     ) * spokes +
  208.                         ( spoke % spokes ) ;
  209.                 indices[j++] = ( ring - 1 ) * spokes +
  210.                         ( spoke % spokes ) ;
  211.             }
  212.         }
  213.     }
  214.  
  215.     pfGSetPrimType( gset, PFGS_TRISTRIPS ) ;
  216.     pfGSetNumPrims( gset, (long)rings ) ;
  217.     pfGSetPrimLengths( gset, length ) ;
  218.     pfGSetAttr( gset, PFGS_COORD3, PFGS_PER_VERTEX, coords, indices ) ;
  219.     pfGSetAttr( gset, PFGS_COLOR4, PFGS_PER_VERTEX, colors, indices ) ;
  220.     pfGSetGState( gset, expGeoState ) ;
  221.  
  222.     pfAddGSet( geode, gset ) ;
  223.  
  224.     return( geode ) ;
  225. }
  226.  
  227.  
  228.  
  229. /*------------------------------------------------------------------------------
  230.  * Initialize explosions.
  231.  *----------------------------------------------------------------------------*/
  232. void
  233. initExplosion(
  234.     void
  235.     )
  236. {
  237.     int        i ;
  238.  
  239.     for( i = 0 ; i < MAXPLAYERS ; i++ )
  240.     {
  241.         explosionGroup[i] = NULL ;
  242.     }
  243.  
  244.     explosionDCS = pfNewDCS() ;
  245.  
  246.     explosionSwitch = pfNewSwitch() ;
  247.     pfSwitchVal( explosionSwitch, PFSWITCH_OFF ) ;
  248.     pfAddChild( explosionDCS, explosionSwitch ) ;
  249.  
  250.     createExplosions( 4, 32, EXPL_FRAMES ) ;
  251. }
  252.  
  253.  
  254.  
  255. /*------------------------------------------------------------------------------
  256.  * Set explosion nodes for a player.
  257.  *----------------------------------------------------------------------------*/
  258. void
  259. addExplosion(
  260.     int    n,
  261.     pfScene    *scene
  262.     )
  263. {
  264.     int        i ;
  265.     pfDCS        *location ;
  266.     pfGroup        *frame ;
  267.  
  268.     if( explosionGroup[n] == NULL )
  269.     {
  270.         explosionGroup[n] = (pfDCS *)pfClone( explosionDCS, 0 ) ;
  271.         pfAddChild( scene, explosionGroup[n] ) ;
  272.     }
  273. }
  274.  
  275.  
  276.  
  277. /*------------------------------------------------------------------------------
  278.  * Set explosion frame and location.
  279.  *----------------------------------------------------------------------------*/
  280. void
  281. setExplosionFrame(
  282.     int    n,
  283.     float    expTime
  284.     )
  285. {
  286.     int        frame ;
  287.     pfDCS        *group ;
  288.     pfMatrix    m ;
  289.     static float    h = 0.75f * CAR_HEIGHT ;
  290.     static float    l = CAR_LENGTH / 6.0f ;
  291.  
  292.     frame = expTime * frameRate ;
  293.  
  294.     group = explosionGroup[n] ;
  295.  
  296.     if( frame >= EXPL_FRAMES )
  297.     {
  298.         pfSwitchVal( EXPLOSION_SWITCH( group ), PFSWITCH_OFF ) ;
  299.     }
  300.     else
  301.     {
  302.         pfSwitchVal( EXPLOSION_SWITCH( group ), frame ) ;
  303.             
  304.         /*
  305.          * Set rotation so that it always faces viewer (3D billboard).
  306.          */
  307.         m[0][0] = -right[0] ;
  308.         m[0][1] = -right[1] ;
  309.         m[0][2] = -right[2] ;
  310.  
  311.         m[1][0] = -ahead[0] ;
  312.         m[1][1] = -ahead[1] ;
  313.         m[1][2] = -ahead[2] ;
  314.  
  315.         m[2][0] = -up[0] ;
  316.         m[2][1] = -up[1] ;
  317.         m[2][2] = -up[2] ;
  318.  
  319.         m[0][3] = 0.0f ;
  320.         m[1][3] = 0.0f ;
  321.         m[2][3] = 0.0f ;
  322.  
  323.         m[3][0] = player[n].xyz[0] +
  324.                 h * player[n].up[0] - l * player[n].ahead[0] ;
  325.         m[3][1] = player[n].xyz[1] +
  326.                 h * player[n].up[1] - l * player[n].ahead[1] ;
  327.         m[3][2] = player[n].xyz[2] +
  328.                 h * player[n].up[2] - l * player[n].ahead[2] ;
  329.         m[3][3] = 1.0f ;
  330.  
  331.         pfDCSMat( group, m ) ;
  332.     }
  333. }
  334.  
  335.  
  336.  
  337. /*------------------------------------------------------------------------------
  338.  * Start the explosion sequence for an enemy.
  339.  *----------------------------------------------------------------------------*/
  340. void
  341. startExplosion(
  342.     int    n
  343.     )
  344. {
  345.     int    i ;
  346.     int    k ;
  347.  
  348.     /*
  349.      * Stop displaying vehicle and (possible)shield.
  350.      */
  351.     for( i = 0 ; i < pfGetNumChildren( trikeSwitch[n] ) ; i++ )
  352.     {
  353.         pfNodeTravMask( pfGetChild( trikeSwitch[n], 0 ), PFTRAV_DRAW,
  354.                 0, PFTRAV_SELF, PF_SET ) ;
  355.     }
  356.     deadTime[n] = gameTime ;
  357. }
  358.  
  359.  
  360.  
  361. /*------------------------------------------------------------------------------
  362.  * End the explosion sequence for an enemy.
  363.  *----------------------------------------------------------------------------*/
  364. void
  365. endExplosion(
  366.     int    n
  367.     )
  368. {
  369.     setExplosionFrame( n, 100.0f ) ;
  370.  
  371.     pfNodeTravMask( pfGetChild( trikeSwitch[n], 0 ), PFTRAV_DRAW,
  372.             0xffffffff, PFTRAV_SELF, PF_SET ) ;
  373.     deadTime[n] = 0.0f ;
  374. }
  375.  
  376.  
  377.  
  378. /*------------------------------------------------------------------------------
  379.  * Delete an explosion due to deleting a player.
  380.  *----------------------------------------------------------------------------*/
  381. void
  382. deleteExplosion(
  383.     int    n,
  384.     pfScene    *scene
  385.     )
  386. {
  387.     int    i ;
  388.  
  389.     if( pfRemoveChild( scene, explosionGroup[n] ) )
  390.     {
  391.         pfDelete( explosionGroup[n] ) ;
  392.     }
  393.     explosionGroup[n] = NULL ;
  394.  
  395.     for( i = n ; i < numberPlayers ; i++ )
  396.     {
  397.         explosionGroup[i] = explosionGroup[i+1] ;
  398.     }
  399. }
  400.